package org.amos.gateway.handler;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import lombok.extern.slf4j.Slf4j;
import org.amos.core.basic.vo.R;
import org.amos.gateway.utils.WebFluxUtils;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebExceptionHandler;
import reactor.core.publisher.Mono;

/**
 * @desc: 自定义限流异常处理
 * @author: liubt
 * @date: 2020-12-17 15:28
 **/
@Slf4j
public class SentinelExceptionHandler implements WebExceptionHandler {
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        ServerHttpResponse response = exchange.getResponse();
        if (response.isCommitted()) {
            return Mono.error(ex);
        }
        if (!BlockException.isBlockException(ex)) {
            return Mono.error(ex);
        }
        String msg = "当前排队人数较多，请稍后再试！";
        if (ex instanceof DegradeException) {
            msg = "当前系统繁忙，请稍后再试！";
        }
        log.debug("[Sentinel异常处理]请求路径:{},异常信息:{}", exchange.getRequest().getPath(), ex.getMessage());
        return writeResponse(exchange,R.error(msg));
    }

    private Mono<Void> writeResponse(ServerWebExchange exchange, R<String> result) {
        return WebFluxUtils.writeJsonResponse(exchange.getResponse(), result);
    }
}
